#include <stdio.h>
#include <stdlib.h>

int compare(const void *a, const void *b) {
	return *(int *) b - *(int *) a;
}

// REVIEW: 本题的实现思路如下。定义一个与源数据数组number[]等长的标记数组flags[]。初始化时，flags全部写0，number获取题目传入的数据。执行判定操作中，我们从第一个flags[]不为1源数据开始操作。（因为flags默认初始化时全部写0，所以这里挑选的必定是number[]中的第一个元素）我们用挑选出来的数进行完整的Callatz猜想。每一轮Callatz猜想中得到的中间数据，与其余对应flags[]值不为1源数据进行对比。如果相等，则将flags[]值改为1。进入下一轮猜想。如此往复，直到猜想结束。下一次，继续寻找flags[]不为1源数据。重复上述操作。直至所有源数据都参与过猜想后，验证阶段结束。输出结果的操作是：遍历flags[]一次，输出flags[]仍为0的对应源数据。
int main() {
	setbuf(stdout, NULL);

	// NOTE: Variable declaration
	int n;


	// NOTE: Inputs
	// STEP: 获取待检验数的个数
	scanf("%d", &n);

	// STEP: 定义源数据和标记动态数组。
	int number[n], flags[n];

	// STEP: 源数据数组number[]初始化
	for (int i = 0; i < n; ++i) {
		scanf("%d", &number[i]);
	}


	// NOTE: Process
	// STEP: 标记数组初始化
	for (int i = 0; i < n; ++i) {
		flags[i] = 0;
	}

	// STEP: 对于n个待测试数进行Callatz猜想验证
	for (int i = 0; i < n; ++i) {
		// HINT: 设置中间变量buf，作为源数据的副本，后续将参与Callatz猜想的运算
		int buf = number[i];

		// HINT: 对于buf进行Callatz猜想
		while (buf != 1) {
			// TODO: 根据数值按奇偶性，进行砍半操作
			if (buf % 2 == 0) {
				// 如果它是偶数，那么把它砍掉一半
				buf /= 2;
			} else {
				// 如果它是奇数，那么把(3 * buf + 1)砍掉一半
				buf = buf * 3 + 1;
				buf /= 2;
			}

			// TODO: 判断中间数据buf与对应flags[]值为0的源数据是否相等？源数据索引值从i+1开始对比。
			for (int j = 0; j < n; ++j) {
				// ALERT: 使用熔断机制加速执行操作（只要flags[]对应元素非0，就没必要继续判断了）
				if (flags[j] == 0 && buf == number[j]) {
					// 更新对应标记数组（代表此数可被覆盖）
					flags[j] = 1;

					// 后续源数据没因不可能存在相同的值，故必要继续遍历对比了
					break;
				}
			}
		}
	}

	// STEP: 使用变量保存下满足条件的源数据个数
	for (int i = 0; i < n; ++i) {
		if (flags[i] == 1) {
			number[i] = 0;
		}
	}

	// STEP: 使用fit_count记录所有满足条件的数据个数。
	int fit_count = 0;
	for (int i = 0; i < n; ++i) {
		if (flags[i] == 0) {
			++fit_count;
		}
	}

	// STEP: 使用快排算法对于子串进行从大到小排序。
	qsort(number, n, sizeof(int), compare);

	// NOTE: Outputs
	// STEP: 输出结果
	for (int i = 0; i < fit_count; ++i) {
		if (i != fit_count - 1) {
			printf("%d ", number[i]);
		} else {
			printf("%d", number[i]);
		}
	}


	// NOTE: Ending
	return 0;
}